﻿using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using Microsoft.EntityFrameworkCore;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using System.Diagnostics;
using RotovapPlatform.Domain.Business.Recipes.Entities.Parameters;

namespace RotovapPlatform.Infrastructure.Common.Data;

/// <summary>
/// 配方数据库上下文
/// 负责管理实验配方的数据访问和持久化
/// </summary>
public class RecipeDbContext : DbContext
{
	/// <summary>
	/// 配方数据集
	/// 用于访问和管理实验配方数据
	/// </summary>
	public DbSet<RecipeDefinition> Recipes { get; set; }

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="options">数据库上下文配置选项</param>
	public RecipeDbContext(DbContextOptions<RecipeDbContext> options)
		: base(options)
	{
		Debug.WriteLine($"RecipeDbContext created with options: {options.ContextType}");
	}

	/// <summary>
	/// 配置实体模型
	/// </summary>
	/// <param name="modelBuilder">模型构建器</param>
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		Debug.WriteLine("Configuring RecipeDbContext model...");

		base.OnModelCreating(modelBuilder);

		modelBuilder.Entity<RecipeDefinition>(entity =>
		{
			entity.ToTable("Recipes");
			entity.HasKey(e => e.RecipeId);
			entity.Property(e => e.ExperimentName).IsRequired().HasMaxLength(100);
			entity.Property(e => e.ExperimentDescription).IsRequired(false).HasMaxLength(500);
			entity.Property(e => e.Operator).IsRequired(false).HasMaxLength(50);
			entity.Property(e => e.ExperimentType).IsRequired().HasConversion<string>();
			entity.Property(e => e.RotovapParameters).IsRequired();
			


			// 配置 JSON 序列化选项
			var options = new JsonSerializerOptions
			{
				Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
				WriteIndented = true
			};

			entity.Property(e => e.RotovapParameters)
				.HasConversion(
					v => JsonSerializer.Serialize(v, options),
					v => JsonSerializer.Deserialize<RotovapParameters>(v, options)!
				);
		});

		Debug.WriteLine("Model configuration completed");
	}

	/// <summary>
	/// 配置数据库连接
	/// </summary>
	/// <param name="optionsBuilder">数据库配置构建器</param>
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
	{
		if (!optionsBuilder.IsConfigured)
		{
			try
			{
				var folder = Path.Combine(
					Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\..\\..\\..\\src\\RotovapPlatform.Infrastructure")),
					"Data");

				Debug.WriteLine($"Database folder path: {folder}");

				if (!Directory.Exists(folder))
				{
					Directory.CreateDirectory(folder);
					Debug.WriteLine($"Created database folder: {folder}");
				}

				var dbPath = Path.Combine(folder, "Rotovap.db");
				Debug.WriteLine($"Database file path: {dbPath}");

				optionsBuilder
					.UseSqlite($"Data Source={dbPath}")
					.LogTo(message => Debug.WriteLine(message));

				Debug.WriteLine("DbContext configured successfully");
			}
			catch (Exception ex)
			{
				Debug.WriteLine($"Error configuring DbContext: {ex}");
				throw;
			}
		}
	}
}